Kotlin

Scope Functions

Swift
                  Person("Alice", 20, "Amsterdam").let {
    println(it)
    it.moveTo("London")
    it.incrementAge()
    println(it)
}
                
                    Person("Alice", 20, "Amsterdam").let {
    print(it)
    it.moveTo("London")
    it.incrementAge()
    print(it)
}
                  
                  val alice = Person("Alice", 20, "Amsterdam")
println(alice)
alice.moveTo("London")
alice.incrementAge()
println(alice)
                
                    let alice = Person("Alice", 20, "Amsterdam")
print(alice)
alice.moveTo("London")
alice.incrementAge()
print(alice)
                  

Context object: this or it

                  fun main() {
    val str = "Hello"
    // this
    str.run {
        println("The receiver string length: $length")
        //println("The receiver string length: ${this.length}") // does the same
    }
​
    // it
    str.let {
        println("The receiver string's length is ${it.length}")
    }
}
                
                    func main() {
    let str = "Hello"
    // this
    str.run {
        print("The receiver string length: $length")
        //print("The receiver string length: ${this.length}") // does the same
    }
​
    // it
    str.let {
        print("The receiver string's length is ${it.length}")
    }
}
                  

this

                  val adam = Person("Adam").apply { 
    age = 20                       // same as this.age = 20 or adam.age = 20
    city = "London"
}
println(adam)
                
                    let adam = Person("Adam").apply { 
    age = 20                       // same as this.age = 20 or adam.age = 20
    city = "London"
}
print(adam)
                  

it

                  fun getRandomInt(): Int {
    return Random.nextInt(100).also {
        writeToLog("getRandomInt() generated value $it")
    }
}
​
val i = getRandomInt()
                
                    func getRandomInt() -> Int {
    return Random.nextInt(100).also {
        writeToLog("getRandomInt() generated value $it")
    }
}
​
let i = getRandomInt()
                  
                  fun getRandomInt(): Int {
    return Random.nextInt(100).also { value ->
        writeToLog("getRandomInt() generated value $value")
    }
}
​
val i = getRandomInt()
                
                    func getRandomInt() -> Int {
    return Random.nextInt(100).also { value ->
        writeToLog("getRandomInt() generated value $value")
    }
}
​
let i = getRandomInt()
                  

Context object

                  val numberList = mutableListOf<Double>()
numberList.also { println("Populating the list") }
    .apply {
        add(2.71)
        add(3.14)
        add(1.0)
    }
    .also { println("Sorting the list") }
    .sort()
                
                    let numberList = mutableListOf<Double>()
numberList.also { print("Populating the list") }
    .apply {
        add(2.71)
        add(3.14)
        add(1.0)
    }
    .also { print("Sorting the list") }
    .sort()
                  
                  fun getRandomInt(): Int {
    return Random.nextInt(100).also {
        writeToLog("getRandomInt() generated value $it")
    }
}
​
val i = getRandomInt()
                
                    func getRandomInt() -> Int {
    return Random.nextInt(100).also {
        writeToLog("getRandomInt() generated value $it")
    }
}
​
let i = getRandomInt()
                  

Lambda result

                  val numbers = mutableListOf("one", "two", "three")
val countEndsWithE = numbers.run { 
    add("four")
    add("five")
    count { it.endsWith("e") }
}
println("There are $countEndsWithE elements that end with e.")
                
                    let numbers = mutableListOf("one", "two", "three")
let countEndsWithE = numbers.run { 
    add("four")
    add("five")
    count { it.endsWith("e") }
}
print("There are $countEndsWithE elements that end with e.")
                  
                  val numbers = mutableListOf("one", "two", "three")
with(numbers) {
    val firstItem = first()
    val lastItem = last()        
    println("First item: $firstItem, last item: $lastItem")
}
                
                    let numbers = mutableListOf("one", "two", "three")
with(numbers) {
    let firstItem = first()
    let lastItem = last()        
    print("First item: $firstItem, last item: $lastItem")
}
                  

let

                  val numbers = mutableListOf("one", "two", "three", "four", "five")
val resultList = numbers.map { it.length }.filter { it > 3 }
println(resultList)
                
                    let numbers = mutableListOf("one", "two", "three", "four", "five")
let resultList = numbers.map { it.length }.filter { $0 > 3 }
print(resultList)
                  
                  val numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { it > 3 }.let { 
    println(it)
    // and more function calls if needed
}
                
                    let numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { $0 > 3 }.let { 
    print(it)
    // and more function calls if needed
}
                  
                  val numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { it > 3 }.let(::println)
                
                    let numbers = mutableListOf("one", "two", "three", "four", "five")
numbers.map { it.length }.filter { $0 > 3 }.let(::println)
                  
                  val str: String? = "Hello"   
//processNonNullString(str)       // compilation error: str can be null
val length = str?.let { 
    println("let() called on $it")        
    processNonNullString(it)      // OK: 'it' is not null inside '?.let { }'
    it.length
}
                
                    let str: String? = "Hello"   
//processNonNullString(str)       // compilation error: str can be null
let length = str?.let { 
    print("let() called on $it")        
    processNonNullString(it)      // OK: 'it' is not null inside '?.let { }'
    it.length
}
                  
                  val numbers = listOf("one", "two", "three", "four")
val modifiedFirstItem = numbers.first().let { firstItem ->
    println("The first item of the list is '$firstItem'")
    if (firstItem.length >= 5) firstItem else "!" + firstItem + "!"
}.toUpperCase()
println("First item after modifications: '$modifiedFirstItem'")
                
                    let numbers = listOf("one", "two", "three", "four")
let modifiedFirstItem = numbers.first().let { firstItem ->
    print("The first item of the list is '$firstItem'")
    if (firstItem.length >= 5) firstItem else "!" + firstItem + "!"
}.toUpperCase()
print("First item after modifications: '$modifiedFirstItem'")
                  

with

                  val numbers = mutableListOf("one", "two", "three")
with(numbers) {
    println("'with' is called with argument $this")
    println("It contains $size elements")
}
                
                    let numbers = mutableListOf("one", "two", "three")
with(numbers) {
    print("'with' is called with argument $this")
    print("It contains $size elements")
}
                  
                  val numbers = mutableListOf("one", "two", "three")
val firstAndLast = with(numbers) {
    "The first element is ${first()}," +
    " the last element is ${last()}"
}
println(firstAndLast)
                
                    let numbers = mutableListOf("one", "two", "three")
let firstAndLast = with(numbers) {
    "The first element is ${first()}," +
    " the last element is ${last()}"
}
print(firstAndLast)
                  

run

                  val service = MultiportService("https://example.kotlinlang.org", 80)
​
val result = service.run {
    port = 8080
    query(prepareRequest() + " to port $port")
}
​
// the same code written with let() function:
val letResult = service.let {
    it.port = 8080
    it.query(it.prepareRequest() + " to port ${it.port}")
}
                
                    let service = MultiportService("https://example.kotlinlang.org", 80)
​
let result = service.run {
    port = 8080
    query(prepareRequest() + " to port $port")
}
​
// the same code written with let() function:
let letResult = service.let {
    it.port = 8080
    it.query(it.prepareRequest() + " to port ${it.port}")
}
                  
                  val hexNumberRegex = run {
    val digits = "0-9"
    val hexDigits = "A-Fa-f"
    val sign = "+-"
​
    Regex("[$sign]?[$digits$hexDigits]+")
}
​
for (match in hexNumberRegex.findAll("+1234 -FFFF not-a-number")) {
    println(match.value)
}
                
                    let hexNumberRegex = run {
    let digits = "0-9"
    let hexDigits = "A-Fa-f"
    let sign = "+-"
​
    Regex("[$sign]?[$digits$hexDigits]+")
}
​
for (match in hexNumberRegex.findAll("+1234 -FFFF not-a-number")) {
    print(match.value)
}
                  

apply

                  val adam = Person("Adam").apply {
    age = 32
    city = "London"        
}
println(adam)
                
                    let adam = Person("Adam").apply {
    age = 32
    city = "London"        
}
print(adam)
                  

also

                  val numbers = mutableListOf("one", "two", "three")
numbers
    .also { println("The list elements before adding new one: $it") }
    .add("four")
                
                    let numbers = mutableListOf("one", "two", "three")
numbers
    .also { print("The list elements before adding new one: $it") }
    .add("four")
                  

takeIf and takeUnless

                  val number = Random.nextInt(100)
​
val evenOrNull = number.takeIf { it % 2 == 0 }
val oddOrNull = number.takeUnless { it % 2 == 0 }
println("even: $evenOrNull, odd: $oddOrNull")
                
                    let number = Random.nextInt(100)
​
let evenOrNull = number.takeIf { $0 % 2 == 0 }
let oddOrNull = number.takeUnless { $0 % 2 == 0 }
print("even: $evenOrNull, odd: $oddOrNull")
                  
                  val str = "Hello"
val caps = str.takeIf { it.isNotEmpty() }?.toUpperCase()
//val caps = str.takeIf { it.isNotEmpty() }.toUpperCase() //compilation error
println(caps)
                
                    let str = "Hello"
let caps = str.takeIf { it.isNotEmpty() }?.toUpperCase()
//let caps = str.takeIf { it.isNotEmpty() }.toUpperCase() //compilation error
print(caps)
                  
                  fun displaySubstringPosition(input: String, sub: String) {
    input.indexOf(sub).takeIf { it >= 0 }?.let {
        println("The substring $sub is found in $input.")
        println("Its start position is $it.")
    }
}
​
displaySubstringPosition("010000011", "11")
displaySubstringPosition("010000011", "12")
                
                    func displaySubstringPosition(input: String, sub: String) {
    input.indexOf(sub).takeIf { $0 >= 0 }?.let {
        print("The substring $sub is found in $input.")
        print("Its start position is $it.")
    }
}
​
displaySubstringPosition("010000011", "11")
displaySubstringPosition("010000011", "12")
                  
                  fun displaySubstringPosition(input: String, sub: String) {
    val index = input.indexOf(sub)
    if (index >= 0) {
        println("The substring $sub is found in $input.")
        println("Its start position is $index.")
    }
}
​
displaySubstringPosition("010000011", "11")
displaySubstringPosition("010000011", "12")
                
                    func displaySubstringPosition(input: String, sub: String) {
    let index = input.indexOf(sub)
    if (index >= 0) {
        print("The substring $sub is found in $input.")
        print("Its start position is $index.")
    }
}
​
displaySubstringPosition("010000011", "11")
displaySubstringPosition("010000011", "12")